package net.atomarrow.util.excel;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.ss.usermodel.Font;

/**
 * 
 * 用户自定义字体类，可以用该类设置字体的大小，颜色等。 该类对象的生成完全脱离POI, 可以由用户创建，使用规范和POI的HSSFCellStyle完全相同
 * 
 * @author Michael
 * 
 */
public class SimpleHSSFFont implements Font {

	private HSSFFont font;
	private String fontName;
	private short fontHeight;
	private short fontHeightInPoints;
	private boolean italic;
	private boolean strikeout;
	private short color;
	private short boldweight;
	private short typeOffset;
	private byte underline;
	private int charSet;

	/**
	 * set the name for the font (i.e. Arial)
	 * 
	 * @param name
	 *            String representing the name of the font to use
	 * @see #FONT_ARIAL
	 */

	public void setFontName(String name) {
		this.fontName = name;
	}

	public void setFontHeight(short height) {
		this.fontHeight = height;
	}

	/**
	 * set the font height
	 * 
	 * @param height
	 *            height in the familiar unit of measure - points
	 * @see #setFontHeight(short)
	 */

	public void setFontHeightInPoints(short height) {
		this.setFontHeight((short) (height * 20));
		this.fontHeightInPoints = height;
	}

	/**
	 * set whether to use italics or not
	 * 
	 * @param italic
	 *            italics or not
	 */

	public void setItalic(boolean italic) {
		this.italic = italic;
	}

	/**
	 * set whether to use a strikeout horizontal line through the text or not
	 * 
	 * @param strikeout
	 *            or not
	 */

	public void setStrikeout(boolean strikeout) {
		this.strikeout = strikeout;
	}

	/**
	 * set the color for the font
	 * 
	 * @param color
	 *            to use
	 * @see #COLOR_NORMAL Note: Use this rather than HSSFColor.AUTOMATIC for
	 *      default font color
	 * @see #COLOR_RED
	 */

	public void setColor(short color) {
		this.color = color;
	}

	/**
	 * set the boldness to use
	 * 
	 * @param boldweight
	 * @see #BOLDWEIGHT_NORMAL
	 * @see #BOLDWEIGHT_BOLD
	 */

	public void setBoldweight(short boldweight) {
		this.boldweight = boldweight;
	}

	/**
	 * set normal,super or subscript.
	 * 
	 * @param offset
	 *            type to use (none,super,sub)
	 * @see #SS_NONE
	 * @see #SS_SUPER
	 * @see #SS_SUB
	 */

	public void setTypeOffset(short offset) {
		this.typeOffset = offset;
	}

	/**
	 * set type of text underlining to use
	 * 
	 * @param underline
	 *            type
	 * @see #U_NONE
	 * @see #U_SINGLE
	 * @see #U_DOUBLE
	 * @see #U_SINGLE_ACCOUNTING
	 * @see #U_DOUBLE_ACCOUNTING
	 */

	public void setUnderline(byte underline) {
		this.underline = underline;
	}

	/**
	 * set character-set to use.
	 * 
	 * @see #ANSI_CHARSET
	 * @see #DEFAULT_CHARSET
	 * @see #SYMBOL_CHARSET
	 */
	public void setCharSet(int charset) {

		this.charSet = charset;
	}

	/**
	 * set character-set to use.
	 * 
	 * @see #ANSI_CHARSET
	 * @see #DEFAULT_CHARSET
	 * @see #SYMBOL_CHARSET
	 */
	public void setCharSet(byte charset) {
		font.setCharSet(charset);
	}

	public String toString() {
		return this.getClass().getName() + "{" + font + "}";
	}

	public HSSFFont getFont() {
		return font;
	}

	public void setFont(HSSFFont font) {
		this.font = font;
	}

	public String getFontName() {
		return fontName;
	}

	public short getFontHeight() {
		return fontHeight;
	}

	public short getFontHeightInPoints() {
		return fontHeightInPoints;
	}

	public boolean getItalic() {
		return italic;
	}

	public boolean getStrikeout() {
		return strikeout;
	}

	public short getColor() {
		return color;
	}

	public short getBoldweight() {
		return boldweight;
	}

	public short getTypeOffset() {
		return typeOffset;
	}

	public byte getUnderline() {
		return underline;
	}

	public int getCharSet() {
		return charSet;
	}

	@Override
	public short getIndex() {
		return font.getIndex();
	}

	/**
	 * 
	 * 该方法是将用户自定义字体所有属性赋给 POI通过WorkBook生成的字体
	 * 
	 * @param font
	 *            用 workbook生成的font
	 */
	public void copyPropertiesToStyle(HSSFFont font) {
		this.font = font;

		Method[] methods = font.getClass().getMethods();
		String fieldName;
		String getterName;
		Method getter;
		Object value;
		for (Method method : methods) {
			String methodName = method.getName();

			if (methodName.startsWith("set")) {
				fieldName = methodName.substring(3);
				getterName = "get" + fieldName;
				//System.out.println(methodName);
				try {
					getter = this.getClass().getMethod(getterName, null);
					value = getter.invoke(this, null);

					if (value != null) {

						if (value instanceof Integer) {

							Method m = font.getClass().getMethod(methodName,
									int.class);
							if (m != null) {

								method = m;
							}
							method.invoke(font, value);
						} else if (value instanceof Byte) {
							Method m = font.getClass().getMethod(methodName,
									byte.class);
							if (m != null) {
								method = m;
							}
							method.invoke(font, value);
						} else {
							method.invoke(font, value);
						}

					}

				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				}
			}

		}
	}

	@Override
	public boolean getBold() {
		return this.font.getBold();
	}

	@Override
	public void setBold(boolean arg0) {
		this.font.setBold(arg0);
	}

}
